package org.blogwu.learn.threadLearn.自己实现一个重入锁.使用AQS;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * 自己实现一个重入锁
 *
 * @author hyf
 * @date 2019-06-24
 **/
public class MyReentrantLock {
    // 定义一个同步器，实现AQS类
    private static class Sync extends AbstractQueuedSynchronizer {
        // 实现tryAcquire(acquires)方法
        @Override
        public boolean tryAcquire(int acquires) {
            // 判断线程是不是一样
            Thread t = getExclusiveOwnerThread();
            // 判断是不是 第一抢到锁和是不是重入
            if (t == null || t == Thread.currentThread()) {
                // 争抢共享变量
                if (compareAndSetState(getState(), getState() + 1)) {
                    // 设置线程拥有者
                    setExclusiveOwnerThread(Thread.currentThread());
                    return true;
                }
            }
            return false;
        }

        // 实现tryRelease(releases)方法
        @Override
        protected boolean tryRelease(int releases) {
            Thread t = getExclusiveOwnerThread();
            if (t != null && t == Thread.currentThread() && getState() > 0) {
                // 争抢共享变量
                if (compareAndSetState(getState(), getState() - 1)) {
                    // 设置线程拥有者
                    if (getState() == 0)
                        setExclusiveOwnerThread(null);
                    return true;
                }
            }
            return true;
        }
    }

    // 声明同步器
    private final Sync sync = new Sync();

    // 加锁
    public void lock() {
        sync.acquire(1);
    }

    // 解锁
    public void unlock() {
        sync.release(1);
    }
}
